package com.socialuni.center.web.serive.user;

import com.socialuni.center.web.factory.CenterMineUserDetailROFactory;
import com.socialuni.center.web.model.RO.user.CenterMineUserDetailRO;
import com.socialuni.center.web.model.VO.PhoneNumVO;
import com.socialuni.center.web.utils.CenterUserUtil;
import com.socialuni.sdk.constant.platform.PlatformType;
import com.socialuni.sdk.constant.platform.ProviderType;
import com.socialuni.sdk.exception.SocialBusinessException;
import com.socialuni.sdk.exception.SocialCustomException;
import com.socialuni.sdk.exception.SocialParamsException;
import com.socialuni.sdk.model.BindPhoneVO;
import com.socialuni.sdk.model.DO.user.AccountDO;
import com.socialuni.sdk.model.DO.user.UserDO;
import com.socialuni.sdk.model.ProviderLoginQO;
import com.socialuni.sdk.model.QO.phone.RefreshWxSessionKeyQO;
import com.socialuni.sdk.model.RO.SocialUserDetailRO;
import com.socialuni.sdk.model.UniUnionIdRO;
import com.socialuni.sdk.model.QO.phone.BindWxPhoneNumQO;
import com.socialuni.sdk.platform.weixin.WxDecode;
import com.socialuni.sdk.repository.AccountRepository;
import com.socialuni.sdk.service.SocialPhoneNumService;
import com.socialuni.sdk.user.phone.SocialBindPhoneNumDomain;
import com.socialuni.sdk.utils.SocialUniProviderUtil;
import com.socialuni.sdk.utils.common.JsonUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;

@Service
@Slf4j
public class CenterPhoneNumService {
    @Resource
    SocialPhoneNumService socialPhoneNumService;

    @Resource
    private AccountRepository accountRepository;

    @Resource
    SocialBindPhoneNumDomain socialBindPhoneNumDomain;


    public CenterMineUserDetailRO userBindPhoneNum(BindPhoneVO bindPhoneVO) {
        UserDO mineUser = CenterUserUtil.getMineUser();
        SocialUserDetailRO socialUserDetailRO = socialPhoneNumService.userBindPhoneNum(bindPhoneVO, mineUser);

        CenterMineUserDetailRO centerUserDetailRO = CenterMineUserDetailROFactory.bindPhoneNumGetMineUserDetail(socialUserDetailRO, mineUser);

        return centerUserDetailRO;
    }

    public void refreshWxSessionKey(RefreshWxSessionKeyQO refreshWxSessionKeyQO) {
        Integer mineUserId = CenterUserUtil.getMineUserId();
        String provider = ProviderType.wx;
        AccountDO accountDO = accountRepository.findByProviderAndUserId(provider, mineUserId);

        //校验各个参数
        if (StringUtils.isEmpty(refreshWxSessionKeyQO.getCode())) {
            log.error("触发了不应该出现的异常，入参为空");
            throw new SocialParamsException("参数异常");
        }
        ProviderLoginQO providerLoginQO = new ProviderLoginQO();
        providerLoginQO.setProvider(provider);
        providerLoginQO.setPlatform(PlatformType.mp);
        providerLoginQO.setCode(refreshWxSessionKeyQO.getCode());

        UniUnionIdRO loginResult = SocialUniProviderUtil.getUnionIdRO(providerLoginQO);

        String sessionKey = loginResult.getSession_key();
        //更新数据库的key
        accountDO.setUserId(mineUserId);
        accountDO.setUpdateTime(new Date());
        //再次更新下sessionkey
        accountDO.setSessionKey(sessionKey);
        accountRepository.save(accountDO);
    }

    //微信绑定手机号方法
    public CenterMineUserDetailRO userBindWxPhoneNum(BindWxPhoneNumQO bindPhoneQO) {
        UserDO mineUser = CenterUserUtil.getMineUser();
        AccountDO accountDO = accountRepository.findByProviderAndUserId(ProviderType.wx, mineUser.getId());
        String sessionKey = accountDO.getSessionKey();
        PhoneNumVO phoneNumVO;
        try {
            String phoneJson = WxDecode.decrypt(sessionKey, bindPhoneQO.getEncryptedData(), bindPhoneQO.getIv());
            phoneNumVO = JsonUtils.objectMapper.readValue(phoneJson, PhoneNumVO.class);
        } catch (Exception e) {
            throw new SocialBusinessException("再点击一次绑定按钮即可完成绑定");
        }
        mineUser = socialBindPhoneNumDomain.checkPhoneNumAndUserBindPhoneNum(mineUser, phoneNumVO.getCountryCode(), phoneNumVO.getPurePhoneNumber());
        //根据用户得到返回详情
        CenterMineUserDetailRO centerUserDetailRO = CenterMineUserDetailROFactory.getMineUserDetail(mineUser);
        return centerUserDetailRO;
    }
}
